package com.pearadmin.modules.ws;

import com.alibaba.fastjson.JSON;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;

/**
 * @author Armando Luo
 * @version 1.0
 * @date 2021/12/18
 */
@Slf4j
public class PearWebSocketHandlerDecoratorFactory implements WebSocketHandlerDecoratorFactory {



    @Override
    public WebSocketHandler decorate(WebSocketHandler handler) {
        return new WebSocketHandlerDecorator(handler) {

            /**
             * websocket 连接时执行动作
             *
             * @param session
             * @throws Exception
             */
            @Override
            public void afterConnectionEstablished(WebSocketSession session) throws Exception {
                String userId =  WebSocketUtil.getUserId(session);
                WebSocketUtil.addSession(userId, session);
                log.info(String.format("用户:%s已上线", userId));
                super.afterConnectionEstablished(session);
            }

            /**
             * websocket 收到消息执行动作
             * @param session
             * @param message
             * @throws Exception
             */
            @Override
            public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
                if (message instanceof TextMessage) {
                    TextMessage textMessage = (TextMessage) message;
                    log.info(String.format("收到用户:%s的消息,内容:%s", WebSocketUtil.getUserId(session),textMessage.getPayload()));
                    try {
                        ClientMessage clientMessage = JSON.parseObject(textMessage.getPayload(), ClientMessage.class);
                        //心跳机制
                        if (ClientMessageType.PING.equals(clientMessage.getType())) {
                            ClientMessage pongMessage = new ClientMessage();
                            pongMessage.setType(ClientMessageType.PONG);
                            WebSocketUtil.send(JSON.toJSONString(pongMessage),  WebSocketUtil.getUserId(session));
                        }

                    } catch (Exception e) {
                        log.error(String.format("消息格式出错,收到错误报文:%s",textMessage.getPayload()));
                    }
                }
                super.handleMessage(session, message);
            }

            /**
             * websocket出错执行动作
             *
             * @param session
             * @param exception
             * @throws Exception
             */
            @Override
            public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
                log.error(String.format("用户:%s,信息处理失败", WebSocketUtil.getUserId(session)),exception);
                super.handleTransportError(session, exception);
            }

            /**
             * websocket关闭连接执行动作
             *
             * @param session
             * @param closeStatus
             * @throws Exception
             */
            @Override
            public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
                String userId = WebSocketUtil.getUserId(session);
                WebSocketUtil.removeSession(userId);
                log.info(String.format("用户:%s已离线", userId));
                super.afterConnectionClosed(session, closeStatus);
            }
        };
    }

    @Data
    public static class ClientMessage{
        private String type;
        private String message;
    }

    @Data
    public static class ClientMessageType {
        public final static String PING = "ping";
        public final static String PONG = "pong";
    }
}


